extends Node
class_name Shaker2D

# 抖动目标节点（支持Node2D或Control）
@export var target_node: Node
# 最大抖动幅度（像素）
@export var max_amplitude: float = 10.0
# 抖动频率（Hz）
@export var frequency: float = 15.0
# 抖动衰减曲线
@export var damping_curve: Curve = Curve.new()

# 当前抖动时间
var _current_time: float = 0.0
# 抖动总持续时间
var _duration: float = 0.0
# 是否正在抖动
var _is_shaking: bool = false
# 初始位置
var _initial_position: Vector2 = Vector2.ZERO
# 目标节点类型（0: 未设置, 1: Node2D, 2: Control）
var _node_type: int = 0

func _ready() -> void:
	if not target_node:
		push_warning("Shaker2D: No target node assigned!")
		set_process(false)
		return
	
	# 检查节点类型
	if target_node is Node2D:
		_node_type = 1
		_initial_position = target_node.position
	elif target_node is Control:
		_node_type = 2
		_initial_position = target_node.position
	else:
		push_error("Shaker2D: Target node must be Node2D or Control!")
		set_process(false)
		return
	
	# 初始化默认曲线
	if damping_curve.get_point_count() == 0:
		damping_curve.add_point(Vector2(0, 1))
		damping_curve.add_point(Vector2(1, 0))

func _process(delta: float) -> void:
	if not _is_shaking or not target_node:
		return
	
	_current_time += delta
	
	if _current_time >= _duration:
		_stop_shake()
		return
	
	# 计算当前抖动强度
	var t: float = _current_time / _duration
	var strength: float = damping_curve.sample(t)
	
	# 生成基于时间的噪声抖动
	var offset: Vector2 = Vector2(
		_perlin_noise(_current_time * frequency, 0.0),
		_perlin_noise(_current_time * frequency, 1.0)
	) * max_amplitude * strength
	
	# 根据节点类型应用抖动
	if _node_type == 1:  # Node2D
		target_node.position = _initial_position + offset
	elif _node_type == 2:  # Control
		target_node.position = _initial_position + offset

# 开始抖动
func start_shake(duration: float, amplitude: float = max_amplitude) -> void:
	if not target_node:
		push_warning("Shaker2D: No target node assigned!")
		return
	
	# 验证节点类型
	if target_node is Node2D:
		_node_type = 1
		_initial_position = target_node.position
	elif target_node is Control:
		_node_type = 2
		_initial_position = target_node.position
	else:
		push_error("Shaker2D: Target node must be Node2D or Control!")
		return
	
	max_amplitude = amplitude
	_duration = duration
	_current_time = 0.0
	_is_shaking = true
	set_process(true)

# 停止抖动
func _stop_shake() -> void:
	_is_shaking = false
	if target_node:
		if _node_type == 1:  # Node2D
			target_node.position = _initial_position
		elif _node_type == 2:  # Control
			target_node.position = _initial_position
	set_process(false)

# 简单的Perlin噪声模拟
func _perlin_noise(time: float, rseed: float) -> float:
	var t: float = time + rseed
	var floor_t: float = floor(t)
	var frac: float = t - floor_t
	var v1: float = sin(floor_t * 123.456 + rseed) * 0.5 + 0.5
	var v2: float = sin((floor_t + 1.0) * 123.456 + rseed) * 0.5 + 0.5
	return lerp(v1, v2, smoothstep(0.0, 1.0, frac))

# 停止抖动的外部接口
func stop() -> void:
	_stop_shake()
